#include "BUTTON.hpp"

#ifdef DBG_TAG
#undef DBG_TAG
#endif
#ifdef DBG_LVL
#undef DBG_LVL
#endif

#define DBG_TAG "button"
#define DBG_LVL DBG_LOG

extern "C"
{
#include <rtdbg.h>
}

BUTTON_SIMPLE::BUTTON_SIMPLE(CHIP_INPUT_PIN *button_pin, button_press_signal_mode press_mode)
{
    if (button_pin == NULL)
    {
        LOG_E("error: button_pin is NULL");
        goto end;
    }
    if (button_pin->CHIP_INPUT_PIN_read_init_status() != chip_pin_status_ok)
    {
        LOG_E("error: button pin init is fail");
        goto end;
    }
    if (button_pin->CHIP_INPUT_PIN_read_pin_mode() != chip_input_pin_mode_simple)
    {
        LOG_E("error: simple button only work in simple input pin mode");
        goto end;
    }

    press_event = rt_event_create("button_event", RT_IPC_FLAG_PRIO);
    if (press_event == RT_NULL)
    {
        LOG_E("error: button event create fail");
        goto end;
    }

    press_lock = rt_mutex_create("button_lock", RT_IPC_FLAG_PRIO);
    if (press_lock == RT_NULL)
    {
        LOG_E("error: button lock create fail");
        goto end;
    }
    this->button_pin = button_pin;
    this->press_tick = 0;
    this->press_mode = press_mode;
    LOG_I("button init ok");
    init_falg = button_status_ok;
    return;
    end:
    LOG_E("error: button_simple init fail");
    init_falg = button_status_fail;
    return;
}
BUTTON_SIMPLE::~BUTTON_SIMPLE()
{
    if (press_lock != RT_NULL) rt_mutex_delete(press_lock);

}

void BUTTON_SIMPLE::BUTTON_SIMPLE_update_in_thread() // 新开一个独立线程并将其放入while(1)中运行
{
    chip_pin_level pin_level;
    pin_level = button_pin->CHIP_INPUT_PIN_read();
    if (pin_level == chip_pin_level_ERROR)
    {
        LOG_E("error: button pin read fail");
        goto end;
    }

//    LOG_W("pin_level %d press_tick %d ",pin_level,press_tick);

    switch (press_mode)
    {
    case button_press_signal_mode_HIGH_active:
        if (pin_level == chip_pin_level_HIGH && press_tick == 0)
        {
            rt_mutex_take(press_lock, RT_WAITING_FOREVER);
            press_tick = rt_tick_get();
            rt_mutex_release(press_lock);
        }
        else if (pin_level == chip_pin_level_LOW) _count_press_time(rt_tick_get());
        break;
    case button_press_signal_mode_LOW_active:
        if (pin_level == chip_pin_level_LOW && press_tick == 0)
        {
            rt_mutex_take(press_lock, RT_WAITING_FOREVER);
            press_tick = rt_tick_get();
            rt_mutex_release(press_lock);
        }
        else if (pin_level == chip_pin_level_HIGH) _count_press_time(rt_tick_get());
        break;

    default:
        break;
    }
    end: return;

}

void BUTTON_SIMPLE::_count_press_time(rt_tick_t release_tick)
{
    int res;

    rt_mutex_take(press_lock, RT_WAITING_FOREVER);
    res = (int) (release_tick - press_tick);
    rt_mutex_release(press_lock);

    if ((int) res == (int) release_tick) goto end;

    if (res > 0 && res < 2000)
    {
        if (rt_event_send(press_event, button_press_signal_pressed) != RT_EOK)
        LOG_E("button send event fail");
    }

    else if (res >= 2000 && res < 5000)
    {
        if (rt_event_send(press_event, button_press_signal_long_pressed) != RT_EOK)
        LOG_E("button send event fail");
    }

    else //(res >= 5000)
    {
        if (rt_event_send(press_event, button_press_signal_long_pressed_5s) != RT_EOK)
        LOG_E("button send event fail");
    }

    end:

//    LOG_W("res %d button %d",res,press_signal);

    rt_mutex_take(press_lock, RT_WAITING_FOREVER);
    press_tick = 0;
    rt_mutex_release(press_lock);
    return;

}
button_press_signal BUTTON_SIMPLE::BUTTON_SIMPLE_read_button_press_status()
{
    uint32_t event_cell;
    button_press_signal back;
    if (rt_event_recv(press_event,
                      (button_press_signal_pressed
                      | button_press_signal_long_pressed
                      | button_press_signal_long_pressed_5s),
                      RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
                      RT_WAITING_FOREVER,
                      &event_cell) != RT_EOK)
    {
        LOG_E("read button event fail");
        return button_press_signal_non_pressed;
    }

    //短按压为最高优先级，默认按压事件不可同时触发
    if (event_cell & button_press_signal_pressed)
        back = button_press_signal_pressed;
    else if (event_cell & button_press_signal_long_pressed)
        back = button_press_signal_long_pressed;
    else if (event_cell & button_press_signal_long_pressed_5s) back = button_press_signal_long_pressed_5s;

    return back;
}

button_status BUTTON_SIMPLE::BUTTON_SIMPLE_read_init_status()
{
    return init_falg;
}
